﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Waiter.Common;
using Waiter.Controler;
using DevComponents.DotNetBar.Controls;
using DevComponents.DotNetBar;

namespace Waiter.View
{
    public partial class frmHoursWork_Edit : DevComponents.DotNetBar.Office2007Form//Form
    {
        #region Init & Global variables*****************************

        WorkShiftCtrl myWorkShiftControl = new WorkShiftCtrl();
        HoursWorkCtrl myHoursWork = new HoursWorkCtrl();
        BindingSource myBinding = new BindingSource();
        bool bflagDontBindingNote = false;
        public delegate void CloseForm();                       //Delegate close form
        public CloseForm myCloseForm;                           //Tạo thể hiện của delegate
 
        public frmHoursWork_Edit()
        {
            InitializeComponent();
        }

        #endregion

        #region Events**********************************************

        private void headerItem1_Load(object sender, EventArgs e)
        {
            //this.headerItem1.init("CHẤM CÔNG", true);
            //this.headerItem1.btnChangeStyle.Visible = false;
            //this.headerItem1.btnSwitchUser.Visible = false;
            //this.headerItem1.lblShift.Visible = false;
            //this.headerItem1.lblShift1.Visible = false;
            ////this.headerItem1.lblName.Text = Waiter.Properties.Settings.Default.STAFF_LOGIN_NAME;
            this.headerItem1.init("CHẤM CÔNG", false);
        }

        /// <summary>
        /// Khi đóng form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmHoursWork_Edit_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (myCloseForm != null)//Thông báo cho form menu
                myCloseForm();
        }

        /// <summary>
        /// Form load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void frmHoursWork_Edit_Load(object sender, EventArgs e)
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.frmHoursWork_Edit_Load", "", "");

            //Control ẩn các panel
            fsControlPanel(false);

            //Load data vào combobox
            myWorkShiftControl.fsLoadWorkShiftList(cmbWorkShift);
            cmbWorkShift_SelectedIndexChanged(new object(), new EventArgs());

            //Load data vào combobox grid
            myHoursWork.fsLoadDataGridViewCombobox_Staff(colSTAFFCODE);

            //Load thông tin init vào các control tại panel search
            fsLoadSearchInitData();
        }        

        /// <summary>
        /// Khi thay đổi trị của combobox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbWorkShift_SelectedIndexChanged(object sender, EventArgs e)
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.cmbWorkShift_SelectedIndexChanged", "", "");

            //Hiển thị thời gian ca làm việc
            List<WORK_SHIFT> myListWS = (List<WORK_SHIFT>)cmbWorkShift.DataSource;

            foreach (var myWS in myListWS)
            {
                if (myWS.CODE == cmbWorkShift.SelectedValue.ToString())
                {
                    lbTime.Text = myWS.START_TIME.ToString() + " - " + myWS.END_TIME.ToString();
                    break;
                }
            }
        }

        /// <summary>
        /// Khi ấn button search
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSearch_Click(object sender, EventArgs e)
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.btnSearch_Click", "", "");

            //Hiển thị các panel
            fsControlPanel(true);

            //Load data vào grid
            //Grid nhân viên
            grdStaff.DataSource = myHoursWork.fsGetStaffGridData(cmbWorkShift.SelectedValue.ToString());
            //Grid giờ làm việc
            bflagDontBindingNote = true;//Đặt cờ để không binding data vào txtNote (sẽ bị error)
            myBinding.DataSource = new HOURS_WORKED();
            myBinding.DataSource = myHoursWork.fsGetHoursWorkedGridData(cmbWorkShift.SelectedValue.ToString(), dateTimeKeeping.Value);
            grdWorkedList.DataSource = myBinding;
            bflagDontBindingNote = false;
            fsBindingExternalData();//binding data vào txtNote
        }        

        /// <summary>
        /// Button Right Arrow Click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRight_Click(object sender, EventArgs e)
        {
            fsMoveDataToTheRight();//Chuyển data sang grid bên phải.
        }

        /// <summary>
        /// Button Left Arrow Click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnLeft_Click(object sender, EventArgs e)
        {
            fsMoveDataToLeft();//Xóa data tại dòng được chọn
        }

        /// <summary>
        /// Khi chọn một dòng trên grid
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void grdWorkedList_SelectionChanged(object sender, EventArgs e)
        {
            this.fsBindingExternalData();//Sẽ binding lại data vào txtNote
        }

        /// <summary>
        /// Khi edit xong tại txtNote thì sẽ lưu data lại
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void txtNote_Leave(object sender, EventArgs e)
        {
            this.fsUpdateNoteData();//Cập nhật data đã chỉnh sửa tại txtNote vào binding source.
        }

        /// <summary>
        /// Khi edit xong tại numTimeLength thì sẽ lưu data lại
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void numWorkedHour_Leave(object sender, EventArgs e)
        {
            this.fsUpdateTimeLengthData();//Cập nhật data đã chỉnh sửa tại numTimeLength vào binding soure.
        }

        /// <summary>
        /// Button Save click
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {            
            fsSaveData();//Save data            
        }

        /// <summary>
        /// Ấn button cancel
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCancel_Click(object sender, EventArgs e)
        {
            //ẩn các panel
            fsControlPanel(false);
        }

        /// <summary>
        /// Ấn button Back
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnBack_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        #endregion

        #region Methods**************************************************

        /// <summary>
        /// Phương thức load trị Init cho các item tại panel search (sẽ lấy trị theo thời gian hiện tại).
        /// </summary>
        private void fsLoadSearchInitData()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsLoadSearchInitData", "", "");

            TimeSpan currentTime = new TimeSpan(DateTime.Now.Hour, DateTime.Now.Minute, DateTime.Now.Second);

            //Lấy giờ hiện tại.
            dateTimeKeeping.Value = DateTime.Now;

            //Chọn ca theo giờ hiện tại
            List<WORK_SHIFT> myListWS = (List<WORK_SHIFT>)cmbWorkShift.DataSource;
            foreach (var myWS in myListWS)
            {
                if (myWS.START_TIME <= currentTime & myWS.END_TIME >= currentTime)
                {
                    cmbWorkShift.SelectedValue = myWS.CODE;
                    break;
                }
            }
        }

        /// <summary>
        /// Phương thức chuyển data từ grid bên trái sang grid bên phải.
        /// </summary>
        private void fsMoveDataToTheRight()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsMoveDataToTheRight", "", "");
            try
            {
                if (grdStaff.CurrentCell.RowIndex > -1)
                {                      
                    string strSelectedStaffCode = grdStaff.Rows[grdStaff.CurrentCell.RowIndex].Cells["colSTAFF_CODE"].Value.ToString();
                    bool bIsRegisWorkShift = Convert.ToBoolean(grdStaff.Rows[grdStaff.CurrentCell.RowIndex].Cells["colIS_REGISED"].Value); 

                    if (myBinding.Count > 0)
                    {
                        //Kiểm tra nếu data đã tồn tại ở grid bên phải thì bỏ qua thao tác
                        for (int i = 0; i < myBinding.Count; i++)
                        {
                            HOURS_WORKED myHW = (HOURS_WORKED)myBinding[i];
                            if (myHW.STAFF_CODE == strSelectedStaffCode)
                                return;
                        }
                    }

                    if (bIsRegisWorkShift == false)
                    {
                        if (MessageBoxEx.Show("Nhân viên này hiện không có đăng ký làm việc tại ca này! Bạn có muốn tiếp tục thao tác này không?", CommonMessages.MSG_CONFIRM_TITLE, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.No)
                            return;
                    }

                    //Thêm mới data vào grid
                    fsAddNewRow(strSelectedStaffCode);
                }
                else
                {
                    MessageBoxEx.Show("Bạn hiện chưa chọn nhân viên nào.", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception ex)
            {
                CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR, "fsMoveDataToTheRight", "", ex.ToString());
                MessageBoxEx.Show("Xuất hiện lỗi khi xử lý dữ liệu. Xin hãy tải lại dữ liệu trên lưới (ấn nút Tìm).", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Xóa data được chọn tại grid grdWorkedList
        /// </summary>
        private void fsMoveDataToLeft()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsMoveDataToLeft", "", "");
            try
            {
                if (myBinding.Count > 0)
                {
                    if (grdWorkedList.CurrentCell.RowIndex > -1)//Kiểm tra xem có dòng data nào được chọn không
                    {
                        string strSelectedCode = grdWorkedList.Rows[grdWorkedList.CurrentCell.RowIndex].Cells["colCODE"].Value.ToString();//Lấy code của dòng được chọn

                        for (int i = 0; i < myBinding.Count; i++)
                        {
                            if (((HOURS_WORKED)myBinding[i]).CODE == strSelectedCode)
                            {
                                myBinding.RemoveAt(i);//Remove dòng được chọn ra khỏi data source
                                break;
                            }
                        }
                    }
                    else
                    {
                        MessageBoxEx.Show("Bạn hiện chưa chọn nhân viên nào.", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_ERROR, "fsMoveDataToTheRight", "", ex.ToString());
                MessageBoxEx.Show("Xuất hiện lỗi khi xử lý dữ liệu. Xin hãy tải lại dữ liệu trên lưới (ấn nút Tìm).", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Add thêm dòng mới vào grid chấm công
        /// </summary>
        /// <param name="pStaffCode"></param>
        private void fsAddNewRow(string pStaffCode)
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsAddNewRow", "", "");

            HOURS_WORKED drNewRow = new HOURS_WORKED();
            List<WORK_SHIFT> myListWS = (List<WORK_SHIFT>)cmbWorkShift.DataSource;

            drNewRow.CODE = String.Format(CommonConstants.CODE_DATE, DateTime.Now);
            drNewRow.WORK_SHIFT_CODE = cmbWorkShift.SelectedValue.ToString();
            drNewRow.CREATE_DATE = dateTimeKeeping.Value;
            foreach (var myWS in myListWS)
            {
                if (myWS.CODE == cmbWorkShift.SelectedValue.ToString())
                {                    
                    drNewRow.START_TIME = myWS.START_TIME;
                    drNewRow.END_TIME = myWS.END_TIME;
                    drNewRow.TIME_LENGHT = myWS.TIME_LENGHT;
                    break;
                }
            }
            drNewRow.STAFF_CODE = pStaffCode;
            drNewRow.NOTE = string.Empty;
            drNewRow.OPID = CommonUtils.fsGetOPID();
            drNewRow.ADD_DATE = DateTime.Now;
            //drNewRow.UPD_DATE = DateTime.Now;
            
            myBinding.Add(drNewRow);
            grdWorkedList.Refresh();
        }

        /// <summary>
        /// Binding data vào Ghi chú
        /// </summary>
        private void fsBindingExternalData()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsBindingExternalData", "", "");

            if (myBinding.Count > 0 && bflagDontBindingNote == false)
            {
                if (grdWorkedList.CurrentCell.RowIndex > -1)
                {
                    string strSelectedCode = grdWorkedList.Rows[grdWorkedList.CurrentCell.RowIndex].Cells["colCODE"].Value.ToString();//Lấy code của dòng được chọn
                    for (int i = 0; i < myBinding.Count; i++)
                    {
                        if (((HOURS_WORKED)myBinding[i]).CODE == strSelectedCode)
                        {
                            txtNote.Text = ((HOURS_WORKED)myBinding[i]).NOTE;
                            numWorkedHour.Value = Convert.ToDouble(((HOURS_WORKED)myBinding[i]).TIME_LENGHT);
                            return;
                        }
                    }

                    //Nếu chưa có data tại numTimeLengt thì set trị mặc định là 4
                    numWorkedHour.Value = 4.0f;
                }
            }
        }

        /// <summary>
        /// Cập nhật data Note vào trong grid
        /// </summary>
        private void fsUpdateNoteData()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsUpdateNoteData", "", "");

            if (myBinding.Count > 0)
            {
                if (grdWorkedList.CurrentCell.RowIndex > -1)
                {
                    string strSelectedCode = grdWorkedList.Rows[grdWorkedList.CurrentCell.RowIndex].Cells["colCODE"].Value.ToString();//Lấy code của dòng được chọn
                    for (int i = 0; i < myBinding.Count; i++)
                    {
                        if (((HOURS_WORKED)myBinding[i]).CODE == strSelectedCode)
                        {
                            ((HOURS_WORKED)myBinding[i]).NOTE = txtNote.Text;
                            break;                           
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Cập nhật data Note vào trong grid
        /// </summary>
        private void fsUpdateTimeLengthData()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsUpdateTimeLengthData", "", "");

            if (myBinding.Count > 0)
            {
                if (grdWorkedList.CurrentCell.RowIndex > -1)
                {
                    string strSelectedCode = grdWorkedList.Rows[grdWorkedList.CurrentCell.RowIndex].Cells["colCODE"].Value.ToString();//Lấy code của dòng được chọn
                    for (int i = 0; i < myBinding.Count; i++)
                    {
                        if (((HOURS_WORKED)myBinding[i]).CODE == strSelectedCode)
                        {
                            ((HOURS_WORKED)myBinding[i]).TIME_LENGHT = numWorkedHour.Value;
                            break;
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Lưu data trên grid
        /// </summary>
        private void fsSaveData()
        {
            CommonLogging.fsWriteLog(CommonConstants.LOG_TYPE_INFO, "frmHoursWork_Edit.fsSaveData", "", "");

            this.btnSave.Enabled = false;
            if (myBinding.Count > 0)//grid có data thì cập nhật
            {
                List<HOURS_WORKED> myHoursWorkList = new List<HOURS_WORKED>();
                for (int i = 0; i < myBinding.Count; i++)
                {
                    myHoursWorkList.Add((HOURS_WORKED)myBinding[i]);
                }

                if (myHoursWork.fsInsertDataHoursWork(myHoursWorkList, cmbWorkShift.SelectedValue.ToString(), dateTimeKeeping.Value) == ResultStatus.SUCCESS)
                {
                    fsControlPanel(false);
                    MessageBoxEx.Show("Thông tin chấm công đã được lưu thành công!", CommonMessages.MSG_NOTICE_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    //Load lại data                    
                    //Grid giờ làm việc
                    bflagDontBindingNote = true;//Đặt cờ để không binding data vào txtNote (sẽ bị error)
                    myBinding.DataSource = new HOURS_WORKED();
                    myBinding.DataSource = myHoursWork.fsGetHoursWorkedGridData(cmbWorkShift.SelectedValue.ToString(), dateTimeKeeping.Value);
                    grdWorkedList.DataSource = myBinding;
                    bflagDontBindingNote = false;
                    fsBindingExternalData();//binding data vào txtNote và numTimeLength
                }
                else
                {
                    this.btnSave.Enabled = false;
                    MessageBoxEx.Show("Lưu dữ liệu thất bại\nXin hãy thử lại.", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else//Grid không có data thì sẽ xóa tất cả các data cũ
            {
                if(MessageBoxEx.Show("Hiện tại không có nhân viên nào được chấm công. Bạn có chắc muốn lưu dữ liệu rỗng", CommonMessages.MSG_CONFIRM_TITLE,  MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
                {
                    if (myHoursWork.fsInsertDataHoursWork(null, cmbWorkShift.SelectedValue.ToString(), dateTimeKeeping.Value) == ResultStatus.SUCCESS)
                    {
                        fsControlPanel(false);
                        MessageBoxEx.Show("Thông tin chấm công đã được lưu thành công!", CommonMessages.MSG_NOTICE_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                    else
                    {
                        this.btnSave.Enabled = false;
                        MessageBoxEx.Show("Lưu dữ liệu thất bại\nXin hãy thử lại.", CommonMessages.MSG_ERR_TITLE, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }

        /// <summary>
        /// Control ẩn hiện các panel
        /// </summary>
        /// <param name="pIsEnable"></param>
        private void fsControlPanel(bool pIsEnable)
        {
            //Điều khiển ẩn hiện các panel
            pnlLeft.Enabled = pIsEnable;
            pnlMiddle.Enabled = pIsEnable;
            pnlRight.Enabled = pIsEnable;
            btnSave.Enabled = pIsEnable;
            btnCancel.Enabled = pIsEnable;

            //panel Top ngược lại với các panel khác
            pnlTop.Enabled = !pIsEnable;
        }

        #endregion
    }
}
